package com.zj.learn.sudoku;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 破解数独
 *
 * @author xi.yang
 * @create 2021-07-31 16:32
 **/
public class SodokuClient {
    public static void main(String[] args) {
        Sodo[] sodos = new Sodo[81];
        char[] nums = SodoMap.sdq5_1.replace(" ", "").toCharArray();
        for (int i = 0; i < nums.length; i++) {
            sodos[i] = new Sodo(i, nums[i]);
        }
        for (Sodo sodo : sodos) {
            sodo.initGroup(sodos);
        }
        printSoduAll(sodos);
        for (Sodo sodo : sodos) {
            sodo.colOpSodo();
        }

        if (validateError(sodos)) {
            System.out.println("============ERROR==========");
            return;
        }
        printSodu(sodos);
        printSoduAll(sodos);
    }

    private static boolean validateError(Sodo[] sodos) {
        List<Sodo[]> allGroup = new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            // 行
            Sodo[] temp = new Sodo[9];
            for (int j = 0; j < 9; j++) {
                temp[j] = sodos[i * 9 + j];
            }
            allGroup.add(temp);
            // 列
            temp = new Sodo[9];
            for (int j = 0; j < 9; j++) {
                temp[j] = sodos[i + j * 9];
            }
            allGroup.add(temp);
        }
//        // 九宫格
//        for (int i = 0; i < 3; i++) {
//            for (int j = 0; j < 3; j++) {
//                int start = i * 27 + j * 3;
//                for (int k = 0; k < 3; k++) {
//                    int index = start + j * 9 + k;
//
//                    System.out.println(index);
//                }
//            }
//        }
        for (Sodo[] temp : allGroup) {
            Map<Integer, Integer> map = new HashMap<>();
            for (Sodo sodo : temp) {
                if (sodo.isOk()) {
                    if (map.containsKey(sodo.getOneVal())) {
                        System.out.println("============ERROR==========" + map.get(sodo.getOneVal()));
                        printSodu(temp);
                        return true;
                    }
                    map.put(sodo.getOneVal(), sodo.getIndex());
                }
            }
        }
        return false;
    }

    /**
     * 打印详细信息
     *
     * @param sodos
     */
    private static void printSoduAll(Sodo[] sodos) {
        int num = 0;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < sodos.length; i++) {
            if (sodos[i].isOk()) {
                num++;
            }
            sb.append(sodos[i].toString()).append("\t");
            if ((i + 1) % 9 == 0) {
                sb.append("\r\n");
            }
        }
        sb.append("\r\n")
                .append("=============")
                .append(num)
                .append("=============");
        System.out.println(sb);
    }

    /**
     * 打印简略信息
     *
     * @param sodos
     */
    private static void printSodu(Sodo[] sodos) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < sodos.length; i++) {
            sb.append(sodos[i].vVal()).append("\t");
            if ((i + 1) % 9 == 0) {
                sb.append("\r\n");
            }
        }
        System.out.println(sb);
    }
}
